package gu.sql2java.velocity;

import static com.gitee.l0km.com4j.base.ConditionChecks.*;

import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import org.apache.commons.collections.ExtendedProperties;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import org.apache.velocity.util.StringUtils;

import com.gitee.l0km.com4j.base.ClassResourceUtils;
import com.gitee.l0km.com4j.base.ClassResourceUtils.TypeFilter;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;

/**
 * 基于 {@link ClasspathResourceLoader}的classpath资源加载器<br>
 * 
 * 支持多路径搜索的 ResourceLoader 实现<br>
 * 对于非'/'开始的资源名,自动添加预设的前缀(prefix)搜索
 * 
 * @author guyadong
 *
 */
public class Sql2javaClasspathResourceLoader extends ClasspathResourceLoader {
    /**
     * The paths to search for templates.
     */
    private List<String> prefix = new ArrayList<>();
	public Sql2javaClasspathResourceLoader() {
	}

	@SuppressWarnings("unchecked")
	@Override
	public void init(ExtendedProperties configuration) {
		Vector<String> vector=configuration.getVector("prefix");
        prefix.addAll( Lists.transform(vector, new Function<String,String>(){

			@Override
			public String apply(final String input) {
				String path = StringUtils.normalizePath(input);
				checkArgument(!Strings.isNullOrEmpty(path),"INVALID resource path prefix [%s]",input);
				if (path.equals("/")){
					return path;
				}
				// 删除末尾的'/'
				return path.endsWith("/") ? path.substring(0, path.length()-1) : path;
			}}) );
        if (log.isTraceEnabled())
        {
            log.trace("Sql2javaClasspathResourceLoader : prefix:" + prefix.toString());
        }
		super.init(configuration);
	}

	@Override
	public InputStream getResourceStream(final String name) throws ResourceNotFoundException {
        if (Strings.isNullOrEmpty(name))
        {
            throw new ResourceNotFoundException ("No template name provided");
        }
		String path = StringUtils.normalizePath(name);
		if (Strings.isNullOrEmpty(path))
        {
            String msg = "No valid template name provided " + name +
                " contains .. and may be trying to access invalid reference";

            log.error("Sql2javaClasspathResourceLoader : " + msg);

            throw new ResourceNotFoundException ( msg );
        }

		if(name.startsWith("/")){
			return toResourceStream(path);
		}
		for(String p:prefix){
			try {
				return toResourceStream(p + path);
			} catch (ResourceNotFoundException e) {
				// CONTINUE
			}
		}
        throw new ResourceNotFoundException( "Sql2javaClasspathResourceLoader Error: cannot find resource " + name );
	}
	private  InputStream toResourceStream(final String path) {
		try {
			// 尝试将path作为文件夹读取文件夹中的文件列表
			List<String> fileList = ClassResourceUtils.getResourceList(getClass(), path,TypeFilter.DEFAULT);
			return new ByteArrayInputStream(Joiner.on("\n").join(fileList).getBytes());
		} catch (FileNotFoundException e) {
			// 尝试将path 作为普通文件路径读取
			return super.getResourceStream(path);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
}
